<template>
    <div class="container">
        <div class="body_wrap">
            <el-card shadow="hover" ref="content_card">
                <el-card class="table_tool_bar_wrap" shadow="never" style="margin-bottom: 10px">
                    <div class="base_wrap">
                        <div class="left">
                            <el-button @click="initCalendar" type="primary" size="medium" icon="el-icon-s-operation">初始化</el-button>
                            <el-button @click="initCalendarHoliday" type="primary" size="medium" icon="el-icon-s-operation">初始化节假日</el-button>
                            <el-button @click="handleAddOrUpdateVisible" type="primary" size="medium" icon="el-icon-s-tools">设置节假日</el-button>
                            <!-- <el-button @click="getBetweenCalendarWorking" type="primary" size="medium" icon="el-icon-plus">获取范围日历</el-button>
                            <el-button @click="getWorkingCount" type="primary" size="medium" icon="el-icon-plus">获取范围工作日历天数</el-button> -->
                        </div>

                        <div class="right">
                            <div class="day_btn">
                                <span class="mr10">
                                    <el-link type="primary" :underline="false">
                                        本月工作天数：{{countWorkDay}} 天
                                    </el-link>
                                </span>
                                <el-date-picker
                                    class="syear"
                                    size="medium"
                                    v-model="selectYear"
                                    value-format="yyyy"
                                    @change="handleSelectYear"
                                    :clearable="false"
                                    :editable="false"
                                    type="year"
                                    placeholder="选择年">
                                </el-date-picker>

                                <el-date-picker
                                    class="smonth"
                                    v-model="selectMonth"
                                    value-format="M"
                                    @change="handleSelectMonth"
                                    :clearable="false"
                                    :editable="false"
                                    type="month"
                                    format="MM"
                                    size="medium"
                                    placeholder="选择月">
                                </el-date-picker>

                                <el-button-group>
                                    <el-button @click="handleQuickChange('prev')" type="primary" size="medium" icon="el-icon-edit">上个月</el-button>
                                    <el-button @click="handleQuickChange('current')" type="primary" size="medium" icon="el-icon-share">今天</el-button>
                                    <el-button @click="handleQuickChange('next')" type="primary" size="medium" icon="el-icon-s-operation">下个月</el-button>
                                </el-button-group>
                            </div>
                        </div>
                    </div>
                </el-card>


                <div class="calendar_wrap" v-loading="loading">
                    <table class="calendar_table">
                        <thead>
                            <tr>
                                <th v-for="(item, i) in weeks" :key="i">
                                    {{ item }}
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(dates, i) in res" :key="i">
                                <td
                                    v-for="(item, index) in dates"
                                    :key="index"
                                    :class="{
                                        notCurMonth: !item.isCurMonth,
                                        currentDay: item.date === curDate
                                    }"
                                >
                                    <!-- 有节假日 -->
                                    <div v-if="map && map.get(item.date)" class="date_wrap">
                                        <div class="date" :class="{weekend: map.get(item.date).weekend == 1}">
                                            {{ item.date.split("-").slice(2).join("-") }}
                                        </div>

                                        <div class="info">
                                            <!-- 节假日 -->
                                            <span :class="{holidy: map.get(item.date).holiday == 1}">
                                                {{map.get(item.date).holiday == 1 ? map.get(item.date).calendarTitle : ""}}
                                            </span>
                                            <!-- 节假日后补班 -->
                                            <span :class="{ weekend: map.get(item.date).weekend == 2 }">
                                                {{
                                                    map.get(item.date).weekend == 2 ?
                                                    map.get(item.date).remarks : ""
                                                }}
                                            </span>
                                            <span class="delSet" v-if="map.get(item.date).holiday == 1 || map.get(item.date).weekend == 2">
                                                <el-link type="danger" @click="handleResetHoliday(item.date)">删除</el-link>
                                            </span>
                                        </div>

                                        <!-- 节假日 -->
                                        <div v-if="map.get(item.date).holiday == 1" class="holiday_rand" :class="{notCurMonth: !item.isCurMonth}">休</div>
                                        <!-- 节假日后补班 -->
                                        <div v-if="map.get(item.date).weekend == 1 && map.get(item.date).working == 1" class="working_rand" :class="{notCurMonth: !item.isCurMonth}">班</div>
                                    </div>
                                    <!-- 未有节假日 -->
                                    <div v-else class="date_wrap">
                                        <div class="date">
                                            {{ item.date.split("-").slice(2).join("-") }}
                                        </div>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </el-card>
        </div>
        <!-- 弹窗, 新增 / 修改 -->
        <AddOrUpdate ref="addOrUpdate" @refreshDataList="getCalendar(selectYear, selectMonth)"></AddOrUpdate>

    </div>
</template>

<script>
import AddOrUpdate from './add-or-update-dialog'
import { getDaysInMonth, handleCrateDate, parseTime } from "./tools.js";
export default {
    components: {
        AddOrUpdate
    },

    data() {
        return {
            loading: false,
            weeks: ["一", "二", "三", "四", "五", "六", "日"],
            curYear: new Date().getFullYear(), // 当前年
            curMonth: new Date().getMonth(), // 当前月
            days: 0, // 当前月总共天数
            curDate: parseTime(new Date().getTime()), // 当前日期 yyyy-MM-dd 格式，用来匹配是否是当前日期
            prevDays: [], // 非当前月的上一月展示的日期
            rearDays: [], // 非当前月的下一月展示的日期
            curDays: [], // 当前月的日期
            showDays: [], // 总共展示的42个日期
            res: [], // 二维数组

            selectYear: new Date().getFullYear().toString(),
            selectMonth: (new Date().getMonth() + 1).toString(),

            countWorkDay: null,

            data: [],
            map: new Map(),
            queryParams: {
                calendarTitle: null,
                weekend: null,
                holiday: null,
                working: null,
                remarks: null,
                ctime: null,
                utime: null
            }
        };
    },
    watch: {
        curMonth: {
            handler(val) {
                this.handleGetDays(this.curYear, val, this.startOfWeek);
            }
        },
        curYear: {
            handler(val) {
                this.handleGetDays(val, this.curMonth, this.startOfWeek);
            }
        }
    },

    created() {
        // 默认渲染当前月
        this.handleGetDays(this.curYear, this.curMonth);
        this.getCalendar(this.selectYear, this.selectMonth);
        this.getWorkingCount()
    },

    mounted() {
        this.$nextTick(() => {});
    },

    methods: {
        /**
         * 新增或编辑
         */
        handleAddOrUpdateVisible() {
            // 表单窗口
            this.$nextTick(() => {
                this.$refs.addOrUpdate.init()
            })
        },

        /**
         * 初始化前端日历
         */
        handleGetDays(year, month) {
            this.showDays = [];
            this.days = getDaysInMonth(year, month);
            let firstDayOfWeek = new Date(`${year}-${month + 1}-01`).getDay();

            if (firstDayOfWeek === 0) {
                // 星期天为0 星期一为1 ，以此类推
                firstDayOfWeek = 7;
            }
            this.prevDays = handleCrateDate(
                year,
                month,
                1,
                firstDayOfWeek,
                "prev"
            );
            this.rearDays = handleCrateDate(
                year,
                month,
                1,
                42 - this.days - (firstDayOfWeek - 1),
                "rear"
            );

            this.curDays = handleCrateDate(year, month, 1, this.days);
            this.showDays.unshift(...this.prevDays);
            this.showDays.push(...this.curDays);
            this.showDays.push(...this.rearDays);
            this.res = this.handleFormatDates(this.showDays);
        },

        handleFormatDates(arr, size = 7) {
            // 传入长度42的原数组，最终转换成二维数组
            const arr2 = [];
            for (let i = 0; i < size; i++) {
                const temp = arr.slice(i * size, i * size + size);
                arr2.push(temp);
            }
            return arr2;
        },

        /**
         * 上月，当天，下月
         */
        handleQuickChange(type) {
            if (type === "prev") {
                this.curMonth--;
                if (this.curMonth === -1) {
                    this.curMonth = 11;
                    this.curYear -= 1;

                    this.selectYear = this.curYear.toString();
                }

                this.selectMonth = this.selectMonth == 0 ? 12 : this.selectMonth;
                this.selectMonth = (parseInt(this.selectMonth) - 1).toString();

                this.getCalendar(this.selectYear, this.selectMonth == 0 ? 12 : this.selectMonth);
                this.getWorkingCount()
            } else if (type === "next") {
                this.curMonth++;
                if (this.curMonth === 12) {
                    this.curMonth = 0;
                    this.curYear += 1;

                    this.selectYear = (parseInt(this.selectYear) + 1).toString();
                }

                this.selectMonth = this.selectMonth == 12 ? 0 : this.selectMonth;
                this.selectMonth = (parseInt(this.selectMonth) + 1).toString();

                this.getCalendar(this.selectYear, this.selectMonth);
                this.getWorkingCount()
            } else if (type === "current") {
                this.curYear = new Date().getFullYear();
                this.curMonth = new Date().getMonth();

                this.selectYear = new Date().getFullYear().toString();
                this.selectMonth = (new Date().getMonth() + 1).toString();

                this.getCalendar(this.selectYear, this.selectMonth);
                this.getWorkingCount()
            }
        },

        /**
         * 年下拉框
         */
        handleSelectYear(val) {
            this.curYear = val;
            this.getCalendar(this.curYear, this.curMonth);
        },

        /**
         * 月下拉框
         */
        handleSelectMonth(val) {
            this.curMonth = val - 1;
            this.getCalendar(this.curYear, val);
            this.getWorkingCount()
        },

        /**
         * 初始化日历
         */
        async initCalendar() {
            this.loading = true;
            const res = await this.$http({
                url: "/hr/calendar/initCalendar",
                method: "GET",
                params: { year: this.selectYear }
            });
            if (this.ResultMessage(res, false)) {
                this.getCalendar(this.selectYear, this.selectMonth);
                this.getWorkingCount()
            }
            this.loading = false;
        },

        /**
         * 初始化日历节假日
         */
        async initCalendarHoliday() {
            this.loading = true;
            const res = await this.$http({
                url: "/hr/calendar/initCalendarHoliday",
                method: "GET",
                params: { year: this.selectYear }
            });
            if (this.ResultMessage(res, false)) {
                this.getCalendar(this.selectYear, this.selectMonth);
            }
            this.loading = false;
        },


        /**
         * 查询某个范围的日历（不包含周末，节假日）
         */
        async getBetweenCalendarWorking() {
            this.loading = true;
            const res = await this.$http({
                url: "/hr/calendar/getBetweenCalendarWorking",
                method: "GET",
                params: {start: '2023-02-01', end: '2023-02-28'}
            });

            this.loading = false;
        },

        /**
         * 查询某个范围的日历（不包含周末，节假日）
         */
        async getWorkingCount() {
            this.loading = true;
            const res = await this.$http({
                url: "/hr/calendar/getWorkingCount",
                method: "GET",
                params: {year: this.selectYear, month: this.selectMonth}
            });
            if (this.ResultMessage(res, false)) {
                this.countWorkDay = res.data
            }
            this.loading = false;
        },

        /**
         * 获取后台日历
         */
        async getCalendar(year, month) {
            const res = await this.$http({
                url: "/hr/calendar/list",
                method: "GET",
                params: { year, month }
            });
            if (this.ResultMessage(res, false)) {
                if(res.data) {
                    this.data = res.data;
                    let map = new Map();
                    this.data.forEach(item => {
                        map.set(item.calendarDate, item);
                    });
                    this.map = map;
                } else {
                    this.$notify({ title: '提示', message: '无'+this.curYear+'年数据，请初始化', type: 'info' });
                }
            }
        },

        /**
         * 重置设置的节假日
         * @param date
         */
        async handleResetHoliday(date) {
            const confirm = await this.$confirm('确定要删除？', '提示', {type: 'warning'}).catch(() => {})
            if (confirm) {
                const res = await this.$http({
                    url: "/hr/calendar/resetHoliday",
                    method: "POST",
                    data: { date }
                });
                if (this.ResultMessage(res, false)) {
                    this.getCalendar(this.selectYear, this.selectMonth);
                }
            }
        }

    }
};
</script>

<style lang="scss" scoped>
.day_btn {
    display: flex;
    justify-content: center;
    align-items: center;
    .syear {
        width: 120px;
        margin-right: 10px;
    }
    .smonth {
        width: 120px;
        margin-right: 10px;
    }
}

.base_wrap{
    .date{
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 20px;
        color: #606266;
    }
}

.calendar_wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}
.calendar_table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    transition: 0.3s;
    thead tr {
        height: 60px;
        font-size: 16px;
    }
    tbody tr {
        &:first-child td {
            border-top: 1px solid #ebeef5;
        }
        td {
            border-bottom: 1px solid #ebeef5;
            border-right: 1px solid #ebeef5;
            border-left: 1px solid #ebeef5;
            vertical-align: top;
            transition: background-color 0.2s ease;
            .date_wrap {
                display: flex;
                flex-direction: column;
                height: 100px;
                position: relative;
                .date {
                    font-family: Helvetica Neue, Helvetica, PingFang SC,
                        Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
                    font-weight: 400;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    flex: 1;
                    font-size: 18px;
                }
                .info {
                    position: absolute;
                    bottom: 0;
                    left: 0;
                    right: 0;
                    box-sizing: border-box;
                    padding: 5px;
                    display: flex;
                    flex: 1;
                    justify-content: center;
                    align-items: center;
                }
                .delSet{
                    position: absolute;
                    top: 0px;
                    right: 10px;
                    bottom: 0;
                    padding: 2px;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    color: #fff;
                    .el-link{
                        font-size: 12px;

                    }
                }

                .holiday_rand {
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    background: green;
                    border-radius: 100%;
                    padding: 2px;
                    width: 20px;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    z-index: 10;
                    color: #fff;
                }
                .working_rand {
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    background: #f73131;
                    border-radius: 100%;
                    padding: 2px;
                    width: 20px;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    color: #fff;
                    z-index: 10;
                }
            }
        }
    }
}

.holidy {
    color: green;
}
.notCurMonth {
    color: #c0c4cc;
    opacity: 0.8;
}
.currentDay {
    color: #1989fa;
    background-color: #f2f8fe;
}
.selectDay {
    color: #fff;
    background-color: #409eff;
}
.rangeSelectd {
    color: #606266;
    background-color: #dee2e9;
}
.weekend {
    color: #f73131;
}
</style>
